namespace PaulRz.Util.Patterns
{
    /// <summary>
    /// Queue with limited size
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public sealed class AutoCleaningQueue<T>
    {
        private T[] array;
        private int size;

        private int pointer = 0;
        private bool filled = false;
        
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="size">size of queue</param>
        public AutoCleaningQueue(int size)
        {
            array = new T[size];
            this.size = size;
        }

        /// <summary>
        /// Get if the queue is full
        /// </summary>
        public bool Filled
        {
            get
            {
                return filled;
            }
        }
        
        /// <summary>
        /// Cleans the queue
        /// </summary>
        public void Clean()
        {
            for(int i=0; i<size; ++i)
            {
                array[i] = default(T);
            }
			pointer = 0;
			filled = false;
        }

        /// <summary>
        /// Add a new element to queue.
        /// If the queue is full, replaces the oldest element in the queue
        /// </summary>
        /// <param name="element"></param>
        public void Add(T element)
        {
            array[pointer] = element;
            pointer++;
            
            if (pointer>=size)
            {
                filled = true;
                pointer = pointer%size;
            }
        }
        
        /// <summary>
        /// Get the latest added element
        /// </summary>
        public T LastAdded
        {
            get
            {
                int lastIndex = pointer - 1;
                if (lastIndex<0)
                {
                    lastIndex += size;
                }
                return array[lastIndex];
            }
        }
        
        /// <summary>
        /// Return the oldest element
        /// </summary>
        public T FirstAdded
        {
            get
            {
                return array[pointer];
            }
        }
        
        /// <summary>
        /// Return the content of the queue
        /// </summary>
        public T[] Datas
        {
            get
            {
                return array;
            }
        }
    }
}
